package cn.admin.remoting.serialize.impl;

import cn.admin.remoting.serialize.CustomSerialization;
import cn.admin.remoting.serialize.DefaultSerialization;
import cn.admin.remoting.serialize.SerializationUtil;
import cn.admin.remoting.serialize.impl.hessian.AliEnumSerializerFactory;
import cn.admin.remoting.util.LoggerInit;
import cn.admin.remoting.util.UnsafeCast;
import com.caucho.hessian.io.SerializerFactory;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

public class SerializationUtilImpl extends SerializationUtil {

    private Map<String,CustomSerialization<?>> customs = Collections.synchronizedMap(new HashMap<>());
    private SerializerFactory serializerFactory = new SerializerFactory();
    private AtomicInteger reuseSerializationFlag = new AtomicInteger(0);
    private static final int REUSE_SERIAL_INIT = 0;
    private static final int REUSE_SERIAL_ENABLE = 1;
    private static final int REUSE_SERIAL_DISABLE = 2;

    public SerializationUtilImpl() {
        this.serializerFactory.addFactory(new AliEnumSerializerFactory());
    }

    @Override
    public void addCustom0(String className, CustomSerialization<?> custom) {
        this.customs.put(className,custom);
    }

    @Override
    public void removeCustom0(String className) {
        this.customs.remove(className);
    }

    @Override
    public CustomSerialization<Object> getCustom0(String className) {
        return UnsafeCast.cast(this.customs.get(className));
    }

    @Override
    public CustomSerialization<Object> getDefaultSerialization0() {
        return DefaultSerialization.instance;
    }

    @Override
    public boolean setReuseSerialization(boolean flag) {
        int newValue = flag ? REUSE_SERIAL_ENABLE : REUSE_SERIAL_DISABLE;
        if (this.reuseSerializationFlag.compareAndSet(REUSE_SERIAL_INIT, newValue)) {
            LoggerInit.LOGGER.warn("**********ReuseSerialization=" + flag);
            return true;
        } else {
            return false;
        }
    }

    @Override
    public boolean isReuseSerialization() {
        return this.reuseSerializationFlag.get() == REUSE_SERIAL_ENABLE;
    }

    @Override
    public SerializerFactory getHessianSerializerFactory() {
        return this.serializerFactory;
    }
}
